﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using Infrastructures;
using Newtonsoft.Json.Linq;

namespace Models
{
    #region Response objects

    public class ResponseStatus
    {
        public string Status { get; set; }
        public string Message { get; set; }

        public static ResponseStatus OK()
        {
            return new ResponseStatus()
            {
                Status = "OK",
                Message = string.Empty
            };
        }

        public static ResponseStatus Error(string message)
        {
            return new ResponseStatus()
            {
                Status = "Error",
                Message = message
            };
        }
    }

    public class StringResponse
    {
        public ResponseStatus Status { get; set; }
        public string ResponseStr { get; set; }

        public StringResponse() { }
    }

    public class ObjectResponse
    {
        public ResponseStatus Status { get; set; }
        public Object ResponseObj { get; set; }

        public ObjectResponse() { }
    }

    public class ListResponse
    {
        public ResponseStatus Status { get; set; }
        public List<Object> ResponseList { get; set; }

        public ListResponse() { }
    }

    public class ModelListResponse
    {
        public ResponseStatus Status { get; set; }
        public ModelList<Object> ResponseList { get; set; }
        public int Count { get; set; }

        public ModelListResponse() { }
    }

    public class DictResponse
    {
        public ResponseStatus Status { get; set; }
        public Dictionary<string, string> ResponseDict { get; set; }

        public DictResponse() { }
    }

    public class JsonResponse
    {
        public ResponseStatus Status { get; set; }
        public JObject ResponseJson { get; set; }

        public JsonResponse() { }
    }

    public class ModelList<T> : List<T>
    {
        private int m_totalcount;

        public int TotalCount
        {
            get { return m_totalcount; }
            set { m_totalcount = value; }
        }

        public ModelList(int totalCount)
        {
            m_totalcount = totalCount;
        }

        public ModelList()
        {
        }

        public ModelList<Object> ToListObject()
        {
            ModelList<Object> lst = new ModelList<Object>();
            this.ForEach(x =>
            {
                lst.Add((Object)x);
            });

            return lst;
        }

        public ModelList(int totalCount, List<T> items)
            : this(totalCount)
        {
            foreach (T item in items)
            {
                this.Add(item);
            }
        }
    }

    #endregion

    #region Objects

    [CommonAttr(PrimaryKey = "UserID")]
    public class LoginInfo : BaseObject
    {
        public int UserID { get; set; }
        public string Name { get; set; }
        public string GroupName { get; set; }
        public APPRole UserType { get; set; }
        public DateTime LoginTime { get; set; }
        public DateTime UpdatedTime { get; set; }
        public string Grade { get; set; }
        public string Logo { get; set; }

        public LoginInfo() { }
    }

    [CacheAttr(PrimaryKey = "AccountValue")]
    [CommonAttr(PrimaryKey = "AccountValue")]
    public class UserValidation
    {
        public int ValidID { get; set; }
        public string UserID { get; set; }
        public AccountType AccountType { get; set; }
        public string AccountValue { get; set; }
        public ValiationType ValidType { get; set; }
        public string ValidNo { get; set; }
        public ValidationStatus ValidStatus { get; set; }
        public DateTime CreatedTime { get; set; }
        public DateTime UpdatedTime { get; set; }

        public UserValidation() { }
    }

    [CommonAttr(PrimaryKey = "SchoolNO")]
    public class School : BaseObject
    {
        public int SchoolNO { get; set; }
        public string SchoolName { get; set; }
        public int StudentSize { get; set; }
        public int ProvinceNO { get; set; }
        public int CityNO { get; set; }
        public int CountyNO { get; set; }
        public string Address { get; set; }

        #region not in db
        public string Province { get; set; }
        public string City { get; set; }
        public string County { get; set; }
        public string DetailSchoolName
        {
            get
            {
                return Province.IsNullOrEmpty() ? City + "-" + County + "-" + SchoolName : Province + "-" + City + "-" + County + "-" + SchoolName;
            }
        }

        public School()
        {

        }
        public School(string schoolName, int provinceNO, int cityNO, int countyNO, string address)
        {
            this.SchoolName = schoolName;
            this.ProvinceNO = provinceNO;
            this.CityNO = cityNO;
            this.CountyNO = countyNO;
            this.Address = address;
        }
        #endregion
    }

    [CommonAttr(PrimaryKey = "RoleNO")]
    public class Money : BaseObject
    {
        public int RoleNO { get; set; }
        public APPRole Fun { get; set; }
        public double CountMoney { get; set; }
        public double Balance { get; set; }
    }

    [CommonAttr(PrimaryKey = "AgentNO")]
    public class Agent : BaseObject
    {
        public int AgentNO { get; set; }
        public string Name { get; set; }
        public int SchoolNO { get; set; }
        public string Resume { get; set; }
        public string LogoPath { get; set; }
        public string Grade { get; set; }
        public DateTime CreateTime { get; set; }
        public DateTime UpdateTime { get; set; }
        public CommonStatus Status { get; set; }
        public string Remark { get; set; }
        public string AgentPassword { get; set; }
        #region not in db
        public UserInfo UserInfo { get; set; }
        public string SchoolName { get; set; }
        #endregion
    }

    [CommonAttr(PrimaryKey = "CompanyNO")]
    public class Company : BaseObject
    {
        public int CompanyNO { get; set; }
        public string Name { get; set; }
        public string ChargeName { get; set; }
        public int TypeNO { get; set; }
        public int JobTypeNO { get; set; }
        public string Sign { get; set; }
        public int SizeNO { get; set; }
        public string CompanyHref { get; set; }
        public string Address { get; set; }
        public string LogoPath { get; set; }
        public string CompanyLDNO { get; set; }
        public double Point { get; set; }
        public string Grade { get; set; }
        public DateTime CreateTime { get; set; }
        public DateTime UpdateTime { get; set; }
        public CommonStatus Status { get; set; }
        public string Remark { get; set; }

        #region not in db

        public string Type { get; set; }
        public string JobType { get; set; }
        public string Size { get; set; }
        public UserInfo UserInfo { get; set; }
        public IList<FileSystem> Files { get; set; }
        public IList<SeldomUsed> ListSeldomUsed { get; set; }

        #endregion

    }

    [CacheAttr(PrimaryKey = "StudentNO")]
    [CommonAttr(PrimaryKey = "StudentNO")]
    public class Student : BaseObject
    {
        public int StudentNO { get; set; }
        public string Name { get; set; }
        public string StudentLDNO { get; set; }
        public string StudentGrade { get; set; }
        public CommonStatus Status { get; set; }
        public string Remark { get; set; }
        public string Education { get; set; }
        public int SchoolNO { get; set; }
        public string Major { get; set; }
        public DateTime EntranceDate { get; set; }
        public DateTime UpdateTime { get; set; }
        public DateTime CreateTime { get; set; }

        #region not in db
        public UserInfo User { get; set; }
        public IList<FileSystem> Files { get; set; }
        public IList<SeldomUsed> ListSeldomUsed { get; set; }
        public School School { get; set; }
        public Association Association { get; set; }
        #endregion

        #region construction
        public Student(int studentNo, string name, string studentLDNo, string education, string major, int schoolNO, DateTime entranceDate)
        {
            this.StudentNO = studentNo;
            this.Name = name;
            this.StudentLDNO = studentLDNo;
            this.Education = education;
            this.Major = major;
            this.SchoolNO = schoolNO;
            this.EntranceDate = entranceDate;
            this.CreateTime = DateTime.Now;
            this.UpdateTime = DateTime.Now;
            this.Status = CommonStatus.Pending;
        }
        public Student()
        {

        }
        #endregion
    }


    public class EventLog : BaseObject
    {
        public int ID { get; set; }
        public string InstanceID { get; set; }
        public string EventID { get; set; }
        public EventType ActionType { get; set; }
        public string ActionObject { get; set; }
        public DateTime ActionTime { get; set; }
        public string Operator { get; set; }
        public string Remark { get; set; }
    }

    [CommonAttr(PrimaryKey = "Code")]
    public class Area : BaseObject
    {
        public int Code { get; set; }
        public string Name { get; set; }
        public AreaFun Fun { get; set; }
        public int Parent { get; set; }
    }

    [CommonAttr(PrimaryKey = "RuleNO")]
    public class BaseData : BaseObject
    {
        public int RuleNO { get; set; }
        public BaseDataFun Fun { get; set; }
        public CommonStatus Status { get; set; }
        public string ValueFrom { get; set; }
        public string ValueTo { get; set; }
        public string Level { get; set; }
        public int Version { get; set; }
        public string Description { get; set; }
        public int ParentNo { get; set; }
        public int DisplayOrder { get; set; }
    }

    [CommonAttr(PrimaryKey = "ID")]
    public class LifecycleEvent : BaseObject
    {
        public int ID { get; set; }
        public int EventID { get; set; }
        public int ParentID { get; set; }
        public APPRole RoleType { get; set; }
        public int RoleNO { get; set; }
        public LifeCycleFun Fun { get; set; }
        public string ValueFrom { get; set; }
        public string ValueTo { get; set; }
        public DateTime UpdatedTime { get; set; }
        public int UpdatedUser { get; set; }
        public string Remark { get; set; }
    }

    [CommonAttr(PrimaryKey = "ProjectID")]
    public class Project : BaseObject
    {
        public int ProjectID { get; set; }
        public string ProjectName { get; set; }
        public string Address { get; set; }
        public double Amount { get; set; }
        public DateTime StartDate { get; set; }
        public DateTime EndDate { get; set; }
        public ProjectStatus Status { get; set; }
        public string Reamrk { get; set; }
        public int CreatorID { get; set; }
        public APPRole CreatorType { get; set; }
        public string CreatorName { get; set; }
        public int CreatorBelongID { get; set; }
        public DateTime CreateDate { get; set; }
        public DateTime UpdateDate { get; set; }
        public int UpdateUser { get; set; }
        public string Cover { get; set; }

        #region not in db

        //public string ProjectCode
        //{
        //    get
        //    {
        //        if (ProjectID == 0)
        //            return string.Empty;

        //        return DataUtil.DESEncrypt(this.ProjectID.ToString());
        //    }
        //}

        public override Dictionary<string, string> ToDictionary()
        {
            Dictionary<string, string> dic = base.ToDictionary();
            dic["ProjectID"] = DataUtil.DESEncrypt(dic["ProjectID"]);
            dic.Remove("CreatorID");
            dic.Remove("UpdateUser");
            dic["CreatorType"] = this.CreatorType.ToString();
            dic["Cover"] = this.Cover.IsNullOrEmpty() ? SystemConfig.Get("DefaultCoverImg") : SystemConfig.Get("UploadHttpPath") + this.Cover;
            dic["StartDate"] = this.StartDate.ToString(DataFormatter.ShortDate);
            dic["EndDate"] = this.EndDate.ToString(DataFormatter.ShortDate);

            return dic;
        }

        #endregion
    }

    [CommonAttr(PrimaryKey = "DataID")]
    public class ProjectData : BaseObject
    {
        public int DataID { get; set; }
        public int ProjectID { get; set; }
        public int ContractID { get; set; }
        public ProjectDataType DataType { get; set; }
        public FieldName DataName { get; set; }
        public string DataValue { get; set; }
        public DateTime UpdateDate { get; set; }
        public int UpdateUser { get; set; }
    }

    [CommonAttr(PrimaryKey = "ContractID")]
    public class ProjectContract : BaseObject
    {
        public int ContractID { get; set; }
        public int ProjectID { get; set; }
        public int AgentID { get; set; }
        public string ContractCode { get; set; }
        public string TemplateVersion { get; set; }
        public CommonStatus Status { get; set; }
        public CommonStatus SubStatus { get; set; }
        public double Amount { get; set; }
        public int ContractorID { get; set; }
        public string ContractorName { get; set; }
        public DateTime CreateDate { get; set; }
        public DateTime SignDate { get; set; }
        public DateTime UpdateDate { get; set; }
        public int UpdateUser { get; set; }
    }

    [CommonAttr(PrimaryKey = "CollectionID")]
    public class ProjectCollection : BaseObject
    {
        public int CollectionID { get; set; }
        public int UserID { get; set; }
        public int ProjectID { get; set; }
        public APPRole ProjectType { get; set; }
        public DateTime CreateDate { get; set; }

        public ProjectCollection(int userID, int projectID, APPRole type)
        {
            this.UserID = userID;
            this.ProjectID = projectID;
            this.ProjectType = type;
        }

        public ProjectCollection() { }
    }

    [CommonAttr(PrimaryKey = "ProjectID")]
    public class ProjectSearch : BaseObject
    {
        public int ProjectID { get; set; }
        public string KeyWords { get; set; }

        public ProjectSearch(int id, string keyWords)
        {
            this.ProjectID = id;
            this.KeyWords = keyWords;
        }
    }

    [CommonAttr(PrimaryKey = "FileNO")]
    public class FileSystem : BaseObject
    {
        public int FileNO { get; set; }
        public FileType Fun { get; set; }
        public APPRole TypeName { get; set; }
        public string InstanceID { get; set; }
        public string Path { get; set; }
        public CommonStatus Status { get; set; }
        public DateTime CtreateTime { get; set; }
        public string OldName { get; set; }
        public string NewName { get; set; }
        public int CreateUser { get; set; }
        public int BelongNO { get; set; }
    }

    [CommonAttr(PrimaryKey = "ID")]
    public class MoneyLog : BaseObject
    {
        public string ID { get; set; }
        public MoneyLogType Type { get; set; }
        public string ValueFrom { get; set; }
        public string ValueTo { get; set; }
        public double Amount { get; set; }
        public CommonStatus Status { get; set; }
        public DateTime CreateTime { get; set; }
        public DateTime UpdateTime { get; set; }
    }

    [CommonAttr(PrimaryKey = "ID")]
    public class SeldomUsed : BaseObject
    {
        public int ID { get; set; }
        public int BelongNo { get; set; }
        public APPRole BelongType { get; set; }
        public SeldomType Type { get; set; }
        public string Value { get; set; }
        public CommonStatus Status { get; set; }

        public SeldomUsed()
        {

        }
        public SeldomUsed(int belongNO, APPRole belongType, SeldomType seldomType, string value)
        {
            this.BelongNo = belongNO;
            this.BelongType = belongType;
            this.Type = seldomType;
            this.Value = value;
            this.Status = CommonStatus.Active;
        }
    }

    [CommonAttr(PrimaryKey = "AssociationNO")]
    public class Association : BaseObject
    {
        public int AssociationNO { get; set; }
        public string Name { get; set; }
        public int SchoolNO { get; set; }
        public string AssociationGrade { get; set; }
        public int ScaleNO { get; set; }
        public int DeptAmount { get; set; }
        public CommonStatus Status { get; set; }
        public string Remark { get; set; }
        public int NatureNO { get; set; }
        public int TypeNO { get; set; }
        public int TypeDetailNO { get; set; }
        public string SchoolType { get; set; }
        public string SelfPassword { get; set; }
        public string UserPassword { get; set; }
        public int CreateUserNO { get; set; }
        public DateTime UpdateTime { get; set; }
        public DateTime CreateTime { get; set; }
        public string LogoPath { get; set; }
        public string ChargeName { get; set; }
        public string SchoolAddress { get; set; }

        #region not in db
        public School School { get; set; }
        public string Nature { get; set; }
        public string Type { get; set; }
        public string TypeDetail { get; set; }
        public string Scale { get; set; }
        public string Grade { get; set; }
        #endregion
        #region construction
        public Association()
        {

        }
        public Association(string name, int createUserID, string schoolType, int typeno, int typeDetailno, int schoolNo, int ScaleNO, int deptAmount, string remark, string logoPath, string address, string chargeName, string grade)
        {
            this.CreateUserNO = createUserID;
            this.SchoolType = schoolType;
            this.TypeNO = typeno;
            this.TypeDetailNO = typeDetailno;
            this.Name = name;
            this.SchoolNO = schoolNo;
            this.LogoPath = logoPath;
            this.ChargeName = chargeName;
            this.SchoolAddress = address;
            this.ScaleNO = ScaleNO;
            this.DeptAmount = deptAmount;
            this.Remark = remark;
            this.UpdateTime = DateTime.Now;
            this.CreateTime = DateTime.Now;
            this.AssociationGrade = grade;
        }

        #endregion
    }

    [CommonAttr(PrimaryKey = "UserNo")]
    public class UserInfo : BaseObject
    {
        public int UserNo { get; set; }
        public string UserName { get; set; }
        public string NickName { get; set; }
        public string Password { get; set; }
        public string Phone { get; set; }
        public string QQ { get; set; }
        public string WeChart { get; set; }
        public APPRole Role { get; set; }
        public string UserType { get; set; }
        public string Email { get; set; }
        public Sex Sex { get; set; }
        public CommonStatus Status { get; set; }
        public DateTime CreateTime { get; set; }
        public DateTime UpdateTime { get; set; }
        public string AgentPassword { get; set; }
        public string HeadImage { get; set; }
        public string SexString { get { if (Sex == Sex.Male)return "男"; else return "女"; } }

        public UserInfo()
        {

        }
        public UserInfo(string phone, string password, APPRole role)
        {
            this.Phone = phone;
            this.UserName = phone;
            this.Password = password;
            this.Role = role;
            this.CreateTime = DateTime.Now;
            this.UpdateTime = DateTime.Now;
            this.Status = CommonStatus.Active;
        }
    }

    [CommonAttr(PrimaryKey = "ID")]
    public class Relationship : BaseObject
    {
        public int ID { get; set; }
        public int NOFrom { get; set; }
        public RelationshipFun Fun { get; set; }
        public int NOTo { get; set; }
        public string NameFrom { get; set; }
        public CommonStatus Status { get; set; }
        public string NameTo { get; set; }
        public DateTime CreateTime { get; set; }

        public Relationship()
        {

        }
        public Relationship(int nofrom, string nameFrom, RelationshipFun fun, int noTo, string nameTo)
        {
            this.NOFrom = nofrom;
            this.NOTo = noTo;
            this.Fun = fun;
            this.NameFrom = nameFrom;
            this.NameTo = nameTo;
        }
    }

    [CommonAttr(PrimaryKey = "ID")]
    public class SpliteWord : BaseObject
    {
        public int ID { get; set; }
        public SpliteWordFun Fun { get; set; }
        public string Value { get; set; }
        public string SpliteValue { get; set; }
    }

    [CommonAttr(PrimaryKey = "ID")]
    public class Validation : BaseObject
    {
        public int ID { get; set; }
        public ValidationFun Fun { get; set; }
        public int ValidateNO { get; set; }
        public string ValidateName { get; set; }
        public CommonStatus ValidStatus { get; set; }
        public string ValueFrom { get; set; }
        public string ValueTo { get; set; }
        public DateTime CreatedTime { get; set; }
        public DateTime UpdatedTime { get; set; }
    }

    [CommonAttr(PrimaryKey = "ID")]
    public class UserMessage : BaseObject
    {
        public int ID { get; set; }
        public UserMessageType MessageType { get; set; }
        public string Sender { get; set; }
        public string Receiver { get; set; }
        public string Content { get; set; }
        public AccountType SendType { get; set; }
        public DateTime SendTime { get; set; }
        public DateTime ReadTime { get; set; }
        public CommonStatus Status { get; set; }
    }

    public class ExceptionMessage : BaseObject
    {
        public string Url { get; set; }
        public string Data { get; set; }
        public string Message { get; set; }
        public string Status { get; set; }
        public string StatusText { get; set; }
    }

    #endregion

    #region Enum

    public enum SearchKey { SchoolName, CompanyName, Area, ActivityType, StudentInterval, StartDate, EndDate, SponsorMoney, SearchFrom, Start, Limit, ProjectStatus, CreatorID, Operator, EventType, EventObject, EventID }
    public enum EventType { All, Create, Update, Delete, SysError, SendCAPTCHA, SendValidMail, SendMessage, SendMsgError, UpdatePassword, Login }
    public enum OrderByColum { CreateTime, Likes, Money, UpdateTime }
    public enum AccountType { Mail, Phone }
    public enum ValiationType { Register, ChangePhone, Authentication, ChangePassword, UpdateInfo, Verified, FiveStep }
    public enum ValidationStatus { Pending, Overdue, Compelted, Failed }
    public enum ProjectFiledFun { Comment, Like, Urgent, FirstFeedback, SecondFeedback, LineTeam, Invoice, ALL }//Invoice 是否可以申请发票
    public enum UserMessageType { SystemMessage }

    public enum FieldName
    {
        Area, AreaDetails, ActivityType, StudentInterval, ActivityNum, Introduction, Supervision, Feedback, ContactName, ContactPhone, Poster, Booth, KTBoard,
        Banner, Microphone, Rollup, Leaflet, Tent, Sound, Desk, Product, Other, Photos, PhotosUrl, Video, VideoUrl, Tweets, TweetsUrl, PublicizeType,
        ExecutiveTeam, CancelRemark, ContractContent, ActivitySummary, PercentageMoney, RejectRemark, ContractStep1Date, ContractStep2Date, ContractStep3Date, ContractStep4Date, ContractStep5Date
    }

    public enum BaseDataFun
    {
        ActivityType, Membership, Level, AssosiationType, OrganizationType, Nature, StudentInterval,
        CompanyInterval, UnsubscribeReason, SponsorLimitAmount, StudentLevel, SponsorMoney, SponsorMultiple,
        CancelRemark, AssociationMaterial, CompanyMaterial, AssociationSize, CheckAssociationRejectedRemark, CheckCompanyRejectedRemark, AssociationSchoolType,
        AssociationRejectRemark, CompanyRejectRemark, AssociationProjectReject, CompanyProjectReject, AgentReward,
        CompanyType, CompanySize, CompanyIndustry, AgentPassword, RebateRate
    }//社团类型（校级/院级），金融类，。学生间隔 ，公司间隔,拒绝的理由，
    public enum ChinaRegion { }
    public enum RelationshipFun { SchoolToAssociation, AssociationToStudent }
    public enum APPRole { Visitor, Company, Student, Agent, Admin, Project, Association }
    public enum ProjectStatus { Draft, Open, Started, Approving, Approved, Rejected, Cancel, Overdue, All, Closed }
    //draft-->Open(审核通过)-->Approving(开始在合作，付款了)-->Approved(合作完成)
    public enum ProjectItemStatus { Draft, Submit, Rejected, Fail, Active, Complete, All, Cancel, Approving }
    public enum Sex { Male, Female }
    public enum CommonStatus { Pending, Confirmed, SponMoneyChanged, Rejected, Overdue, Effective, Cancelled, Deleted, Closed, Verified, Active, Inactive, ForView, All, SecondStep, ThirdStep, FourStep, FiveStep, FeedbackSubmitted, FeedbackRejected, FeedbackApproved, CompanyCancelled, StudentCancelled, FirstPaid }//forView是用来创建出活动给看 但是不审核 也不用来显示在页面
    public enum AssociationTaskStatus { InProgress, Completed, Open }
    public enum FileType { IDFront, IDOpposite, AssoLogo, License, SponsorBook, StuConetnt, StuCover, ActImg, ActImgThumb, ActCover, ActCoverThumb, StuIDCardCover, StuIDCardContent, All, CompanyLogo, AgentLogo }
    public enum ProjectExtendFun { All, Nature, Type, Material, City, Population, School, Province, AgentPassword }
    //undone: 申请尾款 和资金动态
    public enum MoneyStatus { NoPayment, Payment, FirstPay, LastPay }
    public enum ChooseType { StudentChoose, CompanyChoose, SystemChoose, All }
    public enum AreaFun { Province, City, Country }
    public enum LifeCycleFun { ProjectItemStatusChange, ProjectStatusChange, ContractStatusChanged, ContractSubStatusChanged, BookStatusChange, AssociationStatusChange, CompanyStatusChange }
    public enum MoneyLogType { }
    public enum ProjectDataType { Project, Contract }
    public enum SeldomType { AliPayNo, BankNo, PersonCardNo, All }
    public enum SpliteWordFun { School, Company, Association }
    public enum ValidationFun { }
    public enum AssociationGrade { Bronze, Silver }

    #endregion
}
